package com.service;

import java.lang.reflect.Method;
import com.tool.JdbcTool;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

/**
 * 介绍：
 *    service层的祖先类,供其它Service类继承
 ***********************************************************************************************************************************
 * 特点：
 *    ①该类是一个抽象类,从而该类不能new出实例,只能让其子类来new出实例
 *    ②该类内定义了一个私有的非静态内部类,并且此内部类实现了cglib库的MethodInterceptor接口,其实例表示“代理对象的方法调用处理程序”
 ***********************************************************************************************************************************
 * 作用：
 *    ①让该类的子类对象,可以获取到对应的代理对象
 *    ②通过使用代理对象去调用方法,从而实现对被调用的方法进行事务控制的目的
 ***********************************************************************************************************************************       
 * 涉及技术：
 *    ①如何定义私有的非静态内部类
 *    ②如何在父类中创建子类的动态代理对象
 ***********************************************************************************************************************************   
 * 用到的第三方库：
 *    ①cglib
 *        cglib-nodep-3.1.jar
 ***********************************************************************************************************************************
 * 事务：
 *    涉及
 */
public abstract class AncestorService
{
	
	private Object proxy;  //定义一个变量,用来保存“子类对象”的“代理对象”
	
	
	
	/**
	 * 内部类：表示“代理对象的方法调用处理程序”
	 */
	private class TrasationInvocationHandler implements MethodInterceptor
	{
		private Object actualObject;
		private TrasationInvocationHandler(Object actualObject)
		{
			this.actualObject = actualObject;
		}
		@Override
		public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable
		{
			try
			{
				System.err.println("......开启事务......");
				JdbcTool.startTrasation();  //开启事务
				Object returnValue = method.invoke(actualObject, args);
				System.err.println("......提交事务......"+System.lineSeparator());
				JdbcTool.commitTrasation();  //提交事务
				return returnValue;
			}
			catch(Exception e)
			{
				JdbcTool.rollbackTrasation();  //回滚事务
				throw new RuntimeException(e);
			}
			finally
			{
				JdbcTool.closeConnection();  //关闭链接
			}
		}
	}
	
	
	
	
	
	/**
	 * 获取动态代理对象
	 */
	protected final Object getProxy()
	{
		if(proxy == null)
		{
			proxy = Enhancer.create(this.getClass(), new TrasationInvocationHandler(this));  //创建代理对象
		}
		return proxy;
	}
	
	
	
}